/*
 * ElectionManager.cpp
 *
 *  Created on: 12/10/2011
 *      Author: mario
 */

#include "ElectionManager.h"
#include "EleccionDao.h"
#include "../../util/NodoEleccion.h"
#include "../../util/NodoLista.h"
#include "../../util/NodoCandidato.h"
#include "../../util/NodoConteo.h"
#include "../RSA/RSAEncryption.h"


ElectionManager::ElectionManager() {
	this->userManager = new UserManager();
}

Eleccion *ElectionManager::getEleccion() const
{
    return eleccion;
}

Votante *ElectionManager::getUser() const
{
    return user;
}

void ElectionManager::setEleccion(Eleccion *eleccion)
{
    this->eleccion = eleccion;
}

List *ElectionManager::getListas() const
{
    return listas;
}

void ElectionManager::setListas(List *listas)
{
    this->listas = listas;
}

void ElectionManager::setUser(Votante *user)
{
    this->user = user;
}

ElectionManager::~ElectionManager() {
	delete user;
	delete userManager;
}

int ElectionManager::login(int userId, string password)
{
	RSAEncryption* rsa = RSAEncryption::instance();
	Votante *usr = getUserManager()->searchUser(userId, rsa->encrypt(password));
	if(usr == NULL){
		Logger::createEntryLog(Utils::intToString(userId)+" VOTANTE NO VALIDO",Logger::LOG);
		return -1;
	}

	this->setUser(usr);
	return 1;
}



void ElectionManager::logout()
{
	Logger::createEntryLog(Utils::intToString(this->user->getDni())+" LOGOUT",Logger::LOG);

	setUser(NULL);
}



int ElectionManager::selectEleccion(Eleccion* eleccion)
{
	if(getUser() == NULL){
		return -2;
	}
	if(getUser()->getDistrito()->getId() == eleccion->getDistrito()->getId()){
		setEleccion(eleccion);
		return 1;
	}
	return 0;
}

int getConteoId(int lista, int eleccions, int distrito){
	string l = Utils::intToString(lista);
	string e = Utils::intToString(eleccions);
	string d = Utils::intToString(distrito);

	string newId = l + e +d;
	return Utils::stringToInt(newId);
}

//
int ElectionManager::confirmVote(Lista *lista)
{
	int contId = getConteoId(lista->getId(), getEleccion()->getId(), getEleccion()->getDistrito()->getId());
	Conteo* conteo = ResultManager::getConteoPorId(contId);
	bool save = false;
	if (conteo == NULL) {
		conteo = new Conteo();
		conteo->setCantidad(0);
		conteo->setDistrito(getEleccion()->getDistrito());
		conteo->setEleccion(getEleccion());
		conteo->setId(contId);
		conteo->setLista(lista);
		save = true;
	}
	//incremento contador en 1
	conteo->setCantidad(conteo->getCantidad()+1);

	int result = ResultManager::saveConteo(conteo,save);

	if(result == 0){
		Logger::createEntryLog("VOTO GUARDADO",Logger::LOG);
	}else{
		Logger::createEntryLog("ERROR AL GUARDAR EL VOTO",Logger::ERROR);
	}

	delete conteo;
	NodoEleccion* nodo = new NodoEleccion();
	nodo->setNodeValue(lista->getEleccion());

	if(getUser()->getElecciones() == NULL) {
		List* elecs = new List();
		getUser()->setElecciones(elecs);
	}
	getUser()->getElecciones()->add(nodo);

 	int saveUsr = getUserManager()->saveUser(getUser());

 	if(saveUsr == 0){
		Logger::createEntryLog("ELECCION REGISTRADA PARA USUARIO",Logger::LOG);
	}else{
		Logger::createEntryLog("ERROR: REGISTRO DE ELECCION PARA USUARIO",Logger::ERROR);
	}

	return result;
}



//
List *ElectionManager::getListasDisponibles() const
{
	if(getEleccion() == NULL){
		return NULL;
	}
	List* ret = new List();

	tree::BPlusTree* tree = new tree::BPlusTree(LISTAS, BLOCKSIZE);
	tree::Record* record = tree->iterate();
	while(record != NULL){
		stringstream ss(ios_base::in| ios_base::out| ios_base::binary);
		ss.write(record->getData(), record->getDataSize());
		Lista* lista = Lista::toObject(&ss);
		if(lista->getEleccion()->getId() == getEleccion()->getId()){
			NodoLista* nodo = new NodoLista();
			nodo->setNodeValue(lista);
			ret->add(nodo);
		}
		record = tree->iterate();
	}
	return ret;
}

UserManager *ElectionManager::getUserManager() const
{
    return userManager;
}

void ElectionManager::setUserManager(UserManager *userManager)
{
    this->userManager = userManager;
}

List *ElectionManager::getEleccionesDisponibles() const
{
	if(getUser() == NULL){
		return NULL;
	}

	return EleccionDao::searchEleccionesParaVotante(getUser());
}

void ElectionManager::resetEleccion()
{
	setListas(NULL);
	setEleccion(NULL);
}

List* ElectionManager::getResultadosCompletos(int distrito,int eleccion,int lista) {

	return EleccionDao::searchConteos(distrito, eleccion, lista);
}
